www.gusucode.com > VC++ 酒店管理系统-源码程序 > VC++ 酒店管理系统-源码程序/code/hotel2003/CoolTabCtrl.cpp
//Download by http://www.NewXing.com /*#################################################################### Filename: cooltabctrl.cpp ---------------------------------------------------- Remarks: ... ---------------------------------------------------- ####################################################################*/ #include "stdafx.h" #include "resource.h" #include "CoolTabCtrl.h" #include "tools.h" #include<MMSYSTEM.H> #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif /*#################################################################### ------------------------------------------------ class CTabPageItem ------------------------------------------------ ####################################################################*/ CTabPageItem::CTabPageItem(CCoolTabCtrl* pParentWnd, CWnd* pWnd, const CString &strText, int nNumber) { m_pParentWnd = pParentWnd; m_pWnd = pWnd; m_dwState = 0; m_strText = strText; m_nNumber = nNumber; m_hIcon = NULL; } CTabPageItem::~CTabPageItem() { if (m_hIcon != NULL) { DestroyIcon(m_hIcon); m_hIcon = NULL; } } void CTabPageItem::SetIcon(HICON hIcon) { if (m_hIcon != NULL) { DestroyIcon(m_hIcon); m_hIcon = NULL; } m_hIcon = hIcon; } void CTabPageItem::Expend() { m_pWnd->MoveWindow(m_rect); m_pWnd->ShowWindow(SW_SHOW); m_pWnd->UpdateWindow(); } void CTabPageItem::SetRect(const CRect &rect) { m_rect = rect; } void CTabPageItem::Hide() { m_pWnd->ShowWindow(SW_HIDE); } void CTabPageItem::OnDraw(CDC *pDC, int nState) { CRect rect(m_rcLabel); switch (m_pParentWnd->m_nMode) { case TABMODE_NONE: break; case TABMODE_GROUP: { pDC->FillSolidRect(rect, ::GetSysColor(COLOR_3DFACE)); switch (m_dwState) { case 0: pDC->Draw3dRect(rect, RGB(255,255,255), ::GetSysColor(COLOR_3DSHADOW)); break; case 1: pDC->Draw3dRect(rect, ::GetSysColor(COLOR_3DFACE), ::GetSysColor(COLOR_3DFACE)); break; } pDC->SetBkMode(TRANSPARENT); if (m_hIcon != NULL) { ::DrawIconEx( pDC->m_hDC, rect.left + 3, rect.top + 1, m_hIcon, 16, 16, NULL, NULL, DI_NORMAL); } pDC->SetTextColor(RGB(0, 0, 0)); pDC->DrawText(m_strText, rect, DT_CENTER | DT_SINGLELINE |DT_VCENTER); } break; case TABMODE_BOTTOMTAB: { COLORREF backcolor = ::GetSysColor(COLOR_3DFACE); CPen pen(0, 1, AlphaBlendColor(backcolor, 180)); CPen *oldpen = pDC->SelectObject(&pen); if (m_nNumber != m_pParentWnd->m_nActivePage) { rect.DeflateRect(1, 0); } else { rect.DeflateRect(-1, -1, -1, 0); } pDC->MoveTo(rect.left + 2, rect.bottom); pDC->LineTo(rect.right - 1, rect.bottom); pDC->MoveTo(rect.left, rect.top); pDC->LineTo(rect.left, rect.bottom - 1); pDC->MoveTo(rect.right, rect.top); pDC->LineTo(rect.right, rect.bottom - 1); if (m_nNumber == m_pParentWnd->m_nActivePage) { CRect rc(rect); rc.DeflateRect(1, 0, 0, 0); FillGradient(pDC, rc, RGB(255, 255, 255), ::GetSysColor(COLOR_3DFACE)); } else { CRect rc(rect); rc.DeflateRect(1, 0, 0, 0); FillGradient(pDC, rc, RGB(245, 245, 245), ::GetSysColor(COLOR_3DFACE)); } pDC->SetPixel(rect.left + 1, rect.bottom - 1, AlphaBlendColor(backcolor, 180)); pDC->SetPixel(rect.right - 1, rect.bottom - 1, AlphaBlendColor(backcolor, 180)); pDC->SelectObject(oldpen); pDC->SetBkMode(TRANSPARENT); if (m_hIcon != NULL) { ::DrawIconEx( pDC->m_hDC, rect.left + 7, rect.top + 1, m_hIcon, 16, 16, NULL, NULL, DI_NORMAL); rect.left += 18; } rect.top += 2; pDC->SetTextColor(RGB(0, 0, 0)); pDC->DrawText(m_strText, rect, DT_CENTER | DT_SINGLELINE |DT_VCENTER); } break; case TABMODE_TOPTAB: { COLORREF backcolor = ::GetSysColor(COLOR_3DFACE); CPen pen(0, 1, AlphaBlendColor(backcolor, 180)); CPen *oldpen = pDC->SelectObject(&pen); if (m_nNumber != m_pParentWnd->m_nActivePage) { rect.DeflateRect(1, 0); } else { rect.DeflateRect(-1, 0, -1, -1); } pDC->MoveTo(rect.left + 2, rect.top); pDC->LineTo(rect.right - 1, rect.top); pDC->MoveTo(rect.left, rect.top +2); pDC->LineTo(rect.left, rect.bottom); pDC->MoveTo(rect.right, rect.top + 2); pDC->LineTo(rect.right, rect.bottom); if (m_nNumber == m_pParentWnd->m_nActivePage) { CRect rc(rect); rc.DeflateRect(1, 1, 0, 0); FillGradient(pDC, rc, ::GetSysColor(COLOR_3DFACE), RGB(255, 255, 255)); } else { CRect rc(rect); rc.DeflateRect(1, 1, 0, 0); FillGradient(pDC, rc, ::GetSysColor(COLOR_3DFACE), RGB(245, 245, 245)); } pDC->SetPixel(rect.left + 1, rect.top + 1, AlphaBlendColor(backcolor, 180)); pDC->SetPixel(rect.right - 1, rect.top + 1, AlphaBlendColor(backcolor, 180)); pDC->SelectObject(oldpen); pDC->SetBkMode(TRANSPARENT); if (m_hIcon != NULL) { ::DrawIconEx( pDC->m_hDC, rect.left + 7, rect.top + 1, m_hIcon, 16, 16, NULL, NULL, DI_NORMAL); rect.left += 18; } rect.top += 2; pDC->SetTextColor(RGB(0, 0, 0)); pDC->DrawText(m_strText, rect, DT_CENTER | DT_SINGLELINE |DT_VCENTER); } break; default: ASSERT(FALSE); break; } } /*################################################################# ------------------------ 构建,析构函数 ------------------------ #################################################################*/ IMPLEMENT_DYNCREATE(CCoolTabCtrl, CWnd) CCoolTabCtrl::CCoolTabCtrl() { m_nActivePage = 0; m_dwStyle = 0; m_dwBorderStyle = 0; m_nHotItem = 0; m_nMode = TABMODE_NONE; } CCoolTabCtrl::~CCoolTabCtrl() { int count = m_aTabPage.GetSize(); for (int i = 0; i < count; i++) { delete m_aTabPage.GetAt(i); } m_aTabPage.RemoveAll(); } BOOL CCoolTabCtrl::Create(const CRect &rect, CWnd *pParentWnd, UINT dwStyle, UINT dwCtrlStyle, UINT nID) { m_dwStyle = dwCtrlStyle; if (CWnd::Create(AfxRegisterWndClass(CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, AfxGetApp()->LoadStandardCursor(IDC_ARROW), (HBRUSH)GetStockObject(LTGRAY_BRUSH), NULL), NULL, dwStyle, rect, pParentWnd, nID)) { LOGFONT logFont; ZeroMemory((void*)&logFont,sizeof(logFont)); strcpy(logFont.lfFaceName,"宋体"); logFont.lfHeight = -12; logFont.lfWeight = 400; logFont.lfCharSet = GB2312_CHARSET; logFont.lfOutPrecision = 3; logFont.lfClipPrecision = 2; logFont.lfQuality = 1; logFont.lfPitchAndFamily = 2; m_fontWnd.CreateFontIndirect(&logFont); SetFont(&m_fontWnd); return TRUE; } return FALSE; } /*################################################################# ------------------------------- 消息处理函数 CCoolTabCtrl message handlers ------------------------------- #################################################################*/ BEGIN_MESSAGE_MAP(CCoolTabCtrl, CWnd) //{{AFX_MSG_MAP(CCoolTabCtrl) ON_WM_PAINT() ON_WM_ERASEBKGND() ON_WM_NCPAINT() ON_WM_CREATE() ON_WM_NCCALCSIZE() ON_WM_WINDOWPOSCHANGING() ON_WM_NCHITTEST() ON_WM_NCLBUTTONDOWN() ON_WM_MOUSEMOVE() ON_WM_LBUTTONUP() ON_WM_SIZE() ON_WM_LBUTTONDOWN() //}}AFX_MSG_MAP END_MESSAGE_MAP() void CCoolTabCtrl::OnPaint() { CPaintDC dc(this); // device context for painting } void CCoolTabCtrl::OnNcPaint() { CWindowDC windc(this); // device context for painting int count = m_aTabPage.GetSize(); CRect rcWindow, rcClient; GetWindowRect(rcWindow); GetClientRect(&rcClient); ClientToScreen(&rcClient); rcClient.OffsetRect(-rcWindow.TopLeft()); rcWindow.OffsetRect(-rcWindow.TopLeft()); if (rcClient.bottom > rcClient.top && rcClient.right > rcClient.left) { windc.ExcludeClipRect(rcClient); } CMemDC dc(&windc, rcWindow); CFont *oldfont = dc.SelectObject(&m_fontWnd); dc.FillSolidRect(rcWindow, ::GetSysColor(COLOR_3DFACE)); switch (m_nMode) { case TABMODE_NONE: { DrawBoder(&dc, rcClient); } break; case TABMODE_GROUP: { dc.Draw3dRect(rcWindow, RGB(157,157,155), RGB(255,255,255)); } break; case TABMODE_BOTTOMTAB: { DrawBoder(&dc, rcClient); } break; case TABMODE_TOPTAB: { DrawBoder(&dc, rcClient); } break; default: ASSERT(FALSE); break; } if (m_nMode != TABMODE_NONE && count > 0) { for (int i = 0; i < count; i++) { if (i != m_nActivePage) { m_aTabPage.GetAt(i)->OnDraw(&dc, 0); } } ASSERT(m_nActivePage >= 0 && m_nActivePage < count); if (m_nActivePage >= 0 && m_nActivePage < count) { m_aTabPage.GetAt(m_nActivePage)->OnDraw(&dc, 0); } } dc.SelectObject(oldfont); } BOOL CCoolTabCtrl::OnEraseBkgnd(CDC* pDC) { CRect rect; GetClientRect(rect); // pDC->FillSolidRect(rect, RGB(255, 255, 255)); return TRUE; } int CCoolTabCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; return 0; } void CCoolTabCtrl::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS *lpncsp) { CRect rect(lpncsp->rgrc[0]); switch (m_nMode) { case TABMODE_NONE: rect.DeflateRect(2, 2, 4, 4); break; case TABMODE_GROUP: { rect.DeflateRect(1, 1); int count = m_aTabPage.GetSize(); if (count > 0 && m_nActivePage >= 0 && m_nActivePage < count) { rect.top += (m_nActivePage + 1) * 18; rect.bottom -= (count - m_nActivePage - 1) * 18; } } break; case TABMODE_BOTTOMTAB: rect.DeflateRect(2, 2, 4, 20); break; case TABMODE_TOPTAB: rect.DeflateRect(2, 20, 4, 4); break; default: break; } lpncsp->rgrc[0] = rect; } void CCoolTabCtrl::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) { lpwndpos->flags |= SWP_FRAMECHANGED; CWnd::OnWindowPosChanging(lpwndpos); } UINT CCoolTabCtrl::OnNcHitTest(CPoint point) { return HTCAPTION; } void CCoolTabCtrl::OnNcLButtonDown(UINT nHitTest, CPoint point) { SetCapture();//获得鼠标的输入行为 CRect rcWindow; GetWindowRect(rcWindow); int count = m_aTabPage.GetSize(); for (int i = 0; i < count; i++) { CRect rect = m_aTabPage.GetAt(i)->m_rcLabel; rect.OffsetRect(rcWindow.TopLeft()); if (rect.PtInRect(point)) { m_nHotItem = i; m_aTabPage.GetAt(i)->m_dwState = 1; SendMessage(WM_NCPAINT); break; } } PlayResource(IDR_CLICK);//播放声音 } BOOL CCoolTabCtrl::PlayResource(WORD wResourceID) { // Get the handle to the current instance of the application HINSTANCE hInstance = AfxGetInstanceHandle(); ASSERT (hInstance != NULL); // Find the WAVE resource HRSRC hResInfo = FindResource(hInstance, MAKEINTRESOURCE(wResourceID), _T("WAVE")); if(hResInfo == NULL) return FALSE; // Load the WAVE resource HANDLE hRes = LoadResource(hInstance, hResInfo); if (hRes == NULL) return FALSE; // Lock the WAVE resource and play it LPSTR lpRes = (LPSTR) LockResource(hRes); if(lpRes==NULL) return FALSE; if (sndPlaySound(lpRes, SND_MEMORY | SND_ASYNC) == NULL) return FALSE; // Free the WAVE resource and return success or failure. FreeResource(hRes); return TRUE; } void CCoolTabCtrl::OnMouseMove(UINT nFlags, CPoint point) { ClientToScreen(&point); int count = m_aTabPage.GetSize(); if ((nFlags & VK_LBUTTON) && m_nHotItem >= 0 && m_nHotItem < count) { CRect rcWindow; GetWindowRect(rcWindow); CRect rect = m_aTabPage.GetAt(m_nHotItem)->m_rcLabel; rect.OffsetRect(rcWindow.TopLeft()); UINT state = rect.PtInRect(point) ? 1 : 0; if (m_aTabPage.GetAt(m_nHotItem)->m_dwState != state) { m_aTabPage.GetAt(m_nHotItem)->m_dwState = state; SendMessage(WM_NCPAINT); } } CWnd::OnMouseMove(nFlags, point); } void CCoolTabCtrl::OnLButtonUp(UINT nFlags, CPoint point) { ReleaseCapture(); int count = m_aTabPage.GetSize(); if (m_nHotItem >= 0 && m_nHotItem < count) { ClientToScreen(&point); CRect rcWindow; GetWindowRect(rcWindow); CRect rect = m_aTabPage.GetAt(m_nHotItem)->m_rcLabel; rect.OffsetRect(rcWindow.TopLeft()); m_aTabPage.GetAt(m_nHotItem)->m_dwState = 0; if (rect.PtInRect(point) && m_nHotItem != m_nActivePage) { SetActivePage(m_nHotItem); AutoSize(); } SendMessage(WM_NCPAINT); } CWnd::OnLButtonUp(nFlags, point); } /*################################################################# ------------------------------- 控件尺寸处理函数 CCoolTabCtrl size handlers ------------------------------- #################################################################*/ void CCoolTabCtrl::AutoSize() { int count = m_aTabPage.GetSize(); if (count == 0) return; CTabPageItem* page = NULL; if (m_nMode == TABMODE_GROUP && GetSafeHwnd() != NULL) { //强迫窗口重新计算非客户区大小----------------------------- SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW | SWP_NOACTIVATE); } CRect rcWindow, rcClient; GetWindowRect(rcWindow); GetClientRect(rcClient); rcWindow.OffsetRect(-rcWindow.TopLeft()); switch (m_nMode) { case TABMODE_NONE: { for (int i = 0; i < count; i++) { page = m_aTabPage.GetAt(i); if (i != m_nActivePage) { page->Hide(); } else { GetClientRect(rcWindow); page->SetRect(rcWindow); page->Expend(); } } } break; case TABMODE_GROUP: { rcWindow.DeflateRect(1, 1); for (int i = 0; i < count; i++) { page = m_aTabPage.GetAt(i); if (i != m_nActivePage) { page->m_rcLabel = rcWindow; if (m_nActivePage > i) { page->m_rcLabel.top += (i * 18); page->m_rcLabel.bottom = page->m_rcLabel.top + 18; } else { page->m_rcLabel.bottom -= 18 * (count - i - 1); page->m_rcLabel.top = page->m_rcLabel.bottom - 18; } page->m_rect = rcClient; page->Hide(); } else { page->m_rcLabel = rcWindow; page->m_rcLabel.top += (i * 18); page->m_rcLabel.bottom = page->m_rcLabel.top + 18; page->m_rect = rcClient; page->Expend(); } } } break; case TABMODE_BOTTOMTAB: { CRect rc(rcWindow); rc.right = 1; for (int i = 0; i < count; i++) { page = m_aTabPage.GetAt(i); if (i != m_nActivePage) { page->Hide(); } else { page->SetRect(rcClient); page->Expend(); } rc.top = rc.bottom - 18; rc.left = rc.right; rc.right = rc.left + 6 * page->m_strText.GetLength() + 10; if (page->m_hIcon != NULL) rc.right += 20; page->m_rcLabel = rc; } } break; case TABMODE_TOPTAB: { CRect rc(rcWindow); rc.right = 1; for (int i = 0; i < count; i++) { page = m_aTabPage.GetAt(i); if (i != m_nActivePage) { page->Hide(); } else { page->SetRect(rcClient); page->Expend(); } rc.bottom = rc.top + 18; rc.left = rc.right; rc.right = rc.left + 6 * page->m_strText.GetLength() + 10; if (page->m_hIcon != NULL) rc.right += 20; page->m_rcLabel = rc; } } break; default: ASSERT(FALSE); break; } } /*################################################################# ------------------------------- 控件页面处理函数 CCoolTabCtrl page handlers ------------------------------- #################################################################*/ BOOL CCoolTabCtrl::AddPage(CRuntimeClass *pClass, UINT nIDTemplate, LPCTSTR strText, UINT IconID) { CDialog *pDlg = (CDialog*)pClass->CreateObject(); if (pDlg != NULL && pDlg->Create(nIDTemplate, this)) { CTabPageItem *pItem; pItem = new CTabPageItem(this, (CWnd*)pDlg, strText, m_aTabPage.GetSize()); if(IconID != NULL) { pItem->SetIcon(AfxGetApp()->LoadIcon(IconID)); } m_aTabPage.Add(pItem); AutoSize(); return TRUE; } return FALSE; } BOOL CCoolTabCtrl::AddPage(CWnd *pWnd, LPCTSTR strText, UINT IconID) { if (pWnd != NULL) { CTabPageItem *pItem; pItem = new CTabPageItem(this, pWnd, strText, m_aTabPage.GetSize()); if(IconID != NULL) { pItem->SetIcon(AfxGetApp()->LoadIcon(IconID)); } m_aTabPage.Add(pItem); AutoSize(); return TRUE; } return FALSE; } void CCoolTabCtrl::SetCtrlStyle(DWORD dwStyle) { m_dwStyle = dwStyle; } void CCoolTabCtrl::SetBorderStyle(DWORD dwStyle) { m_dwBorderStyle = dwStyle; } void CCoolTabCtrl::SetActivePage(int nindex) { if (m_nActivePage >= 0 && m_nActivePage < m_aTabPage.GetSize()) { m_nActivePage = nindex; AutoSize(); } } void CCoolTabCtrl::SetMode(int nMode) { if (nMode >= 0 && nMode <= TABMODE_BOTTOMTAB) { m_nMode = nMode; if (GetSafeHwnd() != NULL) { AutoSize(); } } } CWnd* CCoolTabCtrl::GetPage(int number) { if (number >= 0 && number < m_aTabPage.GetSize()) { return m_aTabPage.GetAt(number)->m_pWnd; } return NULL; } void CCoolTabCtrl::DrawBoder(CDC *pDC, CRect rect) { COLORREF backcolor = ::GetSysColor(COLOR_3DFACE); rect.InflateRect(1, 1); pDC->Draw3dRect(rect, RGB(255, 255, 255), RGB(255, 255, 255)); rect.InflateRect(1, 1); pDC->Draw3dRect(rect, AlphaBlendColor(backcolor, 180), AlphaBlendColor(backcolor, 180)); CPen pen(0, 1, AlphaBlendColor(backcolor, 220)); CPen *oldpen = pDC->SelectObject(&pen); pDC->MoveTo(rect.left,rect.bottom); pDC->LineTo(rect.right, rect.bottom); pDC->MoveTo(rect.right, rect.top); pDC->LineTo(rect.right, rect.bottom); pen.DeleteObject(); pen.CreatePen(0, 1, AlphaBlendColor(backcolor, 245)); pDC->SelectObject(&pen); pDC->MoveTo(rect.left + 1,rect.bottom + 1); pDC->LineTo(rect.right - 1, rect.bottom + 1); pDC->MoveTo(rect.right + 1, rect.top + 1); pDC->LineTo(rect.right + 1, rect.bottom); pDC->SelectObject(oldpen); } void CCoolTabCtrl::OnSize(UINT nType, int cx, int cy) { CWnd::OnSize(nType, cx, cy); if (GetSafeHwnd() != NULL) { AutoSize(); } } void CCoolTabCtrl::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CWnd::OnLButtonDown(nFlags, point); }